package demo.security.browser;

import demo.security.core.authentication.AbstractChannelSecurityConfig;
import demo.security.core.authentication.mobile.SmsCodeAuthenticationSecurityConfig;
import demo.security.core.props.SecurityConstants;
import demo.security.core.props.SecurityProperties;
import demo.security.core.validate.code.ValidateCodeFilter;
import demo.security.core.validate.code.ValidateCodeSecurityConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;
import org.springframework.social.security.SpringSocialConfigurer;

import javax.sql.DataSource;

/**
 * BroswerSecurityConfig
 *
 * @author lidj
 * @date 2018-01-10
 */
@Configuration
public class BrowserSecurityConfig extends AbstractChannelSecurityConfig{


    @Autowired
    private SecurityProperties securityProperties;

    @Autowired
    private DataSource dataSource;

    @Autowired
    private UserDetailsService userDetailsService;

    @Autowired
    private ValidateCodeSecurityConfig validateCodeSecurityConfig;

    @Autowired
    private SmsCodeAuthenticationSecurityConfig smsCodeAuthenticationSecurityConfig;

    @Autowired
    private SpringSocialConfigurer demoSecuritySocialConfig;

    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }


    @Bean
    public PersistentTokenRepository persistentTokenRepository(){
        JdbcTokenRepositoryImpl  tokenRepository  = new JdbcTokenRepositoryImpl();
        tokenRepository.setDataSource(dataSource);
        return tokenRepository;
    }


    /**
     * 配置身份认证和授权
     * @param http
     * @throws Exception
     */
    @Override
    protected void configure(HttpSecurity http) throws Exception {

       applyPasswordAuthenticationConfig(http);

       http.apply(validateCodeSecurityConfig)
               .and().apply(smsCodeAuthenticationSecurityConfig)
               .and().apply(demoSecuritySocialConfig)
               .and()
               .rememberMe()
               .tokenRepository(persistentTokenRepository())
               .tokenValiditySeconds(securityProperties.getBrowser().getRememberMeSeconds())
               .userDetailsService(userDetailsService)
               .and()
               .authorizeRequests()
               .antMatchers(
                       SecurityConstants.DEFAULT_UNAUTHENTICATION_URL,
                       SecurityConstants.DEFAULT_LOGIN_PROCESSING_URL_MOBILE,
                       securityProperties.getBrowser().getLoginPage(),
                       securityProperties.getBrowser().getSignUpUrl(),
                       "/user/regist",
                       SecurityConstants.DEFAULT_VALIDATE_CODE_URL_PREFIX+"/*"
               ).permitAll()
               .anyRequest()
               .authenticated()
               .and()
               .csrf().disable();
    }
}
